*** dbinc/mp.h	2007-09-28 01:28:25.000000000 +1000
--- dbinc/mp.h	2008-02-14 01:22:09.000000000 +1100
***************
*** 639,644 ****
--- 639,647 ----
   */
  #define	MP_TRUNC_RECOVER	0x01
  
+ /* Private flags to DB_MPOOLFILE->close. */
+ #define	DB_MPOOL_NOLOCK		0x002	/* Already have mpf locked. */
+ 
  #if defined(__cplusplus)
  }
  #endif
*** mp/mp_fopen.c	2007-05-18 03:18:01.000000000 +1000
--- mp/mp_fopen.c	2008-02-12 16:09:42.000000000 +1100
***************
*** 888,894 ****
  	 * when we try to flush them.
  	 */
  	deleted = 0;
! 	MUTEX_LOCK(dbenv, mfp->mutex);
  	if (F_ISSET(dbmfp, MP_MULTIVERSION))
  		--mfp->multiversion;
  	if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) {
--- 888,895 ----
  	 * when we try to flush them.
  	 */
  	deleted = 0;
! 	if (!LF_ISSET(DB_MPOOL_NOLOCK))
! 		MUTEX_LOCK(dbenv, mfp->mutex);
  	if (F_ISSET(dbmfp, MP_MULTIVERSION))
  		--mfp->multiversion;
  	if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) {
***************
*** 909,921 ****
  			}
  		}
  		if (mfp->block_cnt == 0) {
  			if ((t_ret =
  			    __memp_mf_discard(dbmp, mfp)) != 0 && ret == 0)
  				ret = t_ret;
  			deleted = 1;
  		}
  	}
! 	if (!deleted)
  		MUTEX_UNLOCK(dbenv, mfp->mutex);
  
  done:	/* Discard the DB_MPOOLFILE structure. */
--- 910,928 ----
  			}
  		}
  		if (mfp->block_cnt == 0) {
+ 			/*
+ 			 * We should never discard this mp file if our caller
+ 			 * is holding the lock on it.  See comment in
+ 			 * __memp_sync_file.
+ 			 */
+ 			DB_ASSERT(dbenv, !LF_ISSET(DB_MPOOL_NOLOCK));
  			if ((t_ret =
  			    __memp_mf_discard(dbmp, mfp)) != 0 && ret == 0)
  				ret = t_ret;
  			deleted = 1;
  		}
  	}
! 	if (!deleted && !LF_ISSET(DB_MPOOL_NOLOCK))
  		MUTEX_UNLOCK(dbenv, mfp->mutex);
  
  done:	/* Discard the DB_MPOOLFILE structure. */
*** mp/mp_sync.c	2007-06-02 04:32:44.000000000 +1000
--- mp/mp_sync.c	2008-02-12 16:09:42.000000000 +1100
***************
*** 755,761 ****
  	 * This is important since we are called with the hash bucket
  	 * locked.  The mfp will get freed via the cleanup pass.
  	 */
! 	if (dbmfp != NULL && (t_ret = __memp_fclose(dbmfp, 0)) != 0 && ret == 0)
  		ret = t_ret;
  
  	--mfp->mpf_cnt;
--- 755,762 ----
  	 * This is important since we are called with the hash bucket
  	 * locked.  The mfp will get freed via the cleanup pass.
  	 */
! 	if (dbmfp != NULL &&
! 	    (t_ret = __memp_fclose(dbmfp, DB_MPOOL_NOLOCK)) != 0 && ret == 0)
  		ret = t_ret;
  
  	--mfp->mpf_cnt;

